<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .big {
      width: 400px;
      height: 400px;
      background-color: red;
    }

    .mid {
      width: 200px;
      height: 200px;
      background-color: blue;
    }

    .sma {
      width: 100px;
      height: 100px;
      background-color: black;
    }

    ul {
      list-style: none;
      width: 400px;
      padding: 0;
      background-color: #ccc;
    }

    li {
      border: 1px solid black;
    }

    li:not(li:nth-last-of-type(1)) {
      border-bottom: none;
    }

    li:nth-last-of-type(1) {
      margin-bottom: 0;
    }
  </style>
</head>

<body>
  <!-- 
    事件监听：
      主流浏览器：
        addEventListener('事件'，处理函数，在什么阶段处理(布尔值)) 默认为false 
      IE8以下浏览器：
        attachEvent('事件',处理函数)

      事件流的两个阶段：
        点击的时候，电脑首先会判断：
          点击的是浏览器；
          点击的是document；
          点击的是html ==> body ==> 目标元素

        捕获阶段：true
          从浏览器本身 ==> 元素本身

        冒泡阶段：fasle
          从元素本身出发 ==> 浏览器上

        事件流带来的问题：
          一个元素的事件可能会触发其他元素的事件，带来一些不必要的事件冲突；

        事件流的拦截方法：
          1.各自触发各自的事件 相互独立 互不影响：
            让所有事件都冒泡触发，然后在目标元素中拦截其他事件的冲突；
            e.stopPropagation() 阻止事件进一步传递
          
          2.不管在什么元素里，都只能触发最外层的元素的事件：
            让所有事件都在捕获阶段触发，然后分别拦截；

    清除事件监听：
      主流浏览器：
        removeEventListener('事件'，处理函数名)
        一定要写具体的函数名，不然没法清除

      IE8以下：
        detachEvent('事件',处理函数名)

    事件代理：
      是一种设计模式：即观察者模式
      使用事件对象的 target 即 事件的目标
   -->

  <div class="big">
    <div class="mid">
      <div class="sma"></div>
    </div>
  </div>

  <ul class="list">
    <li>1dsagjda</li>
    <li>28545</li>
    <li>381454</li>
    <li>4dhsajdh456</li>
    <li>dhgsadasjh</li>
  </ul>

  <script>
    // 事件监听列举
    const divs = [...document.querySelectorAll('div')]

    // 这就是一种冒泡阶段触发 改成true就变成捕获阶段触发
    for (const div of divs) {
      div.addEventListener('click', deal)
      div.addEventListener('click', remove)
    }

    // 处理函数1
    function deal(e) {
      e.stopPropagation() // 阻止冒泡 后续事件就不会被传递了
      console.log(this.className + '被点击了')
    }

    // 处理函数2
    function remove(e) {
      e.stopPropagation() // 阻止冒泡 后续事件就不会被传递了
      console.log(this.className + '没了')
    }

    // 取消处理函数2的事件监听
    for (const div of divs) {
      div.removeEventListener('click', remove)
    }

    // 事件代理
    // 点击每个 li 标签 就打印相应的HTML内容

    // 不必给每一个 li 都绑定一个 事件监听
    // 只需要 给 ul 标签绑定事件监听 然后再去寻找 每个 li 标签

    const list = document.querySelector('.list')

    list.addEventListener('click', print)

    function print(e) {

      const target = e.target

      if (target.tagName.toLowerCase() === 'li') {

        // 只打印数值
        if (/^\d+$/.test(target.innerHTML)) {
          console.log(target.innerHTML)
        }
      }

    }

    // 可以后续添加一个元素 依然可以被点击触发事件
    const li = document.createElement('li')
    li.innerHTML = 456456
    list.appendChild(li)
  </script>
</body>

</html>